package com.ks.common.quartz;

import org.apache.log4j.Logger;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class QuartzManager {

    private static final org.apache.log4j.Logger log =  Logger.getLogger(QuartzManager.class);

    private static volatile QuartzManager instance;

    public static QuartzManager getInstance(){
        if(null == instance){
            synchronized (QuartzManager.class){
                if(null == instance){
                    instance = new QuartzManager();
                }
            }
        }
        return instance;
    }

    public void init(){
        try {
            //1.创建Scheduler的工厂
            SchedulerFactory sf = new StdSchedulerFactory();

            //2.从工厂中获取调度器实例
            Scheduler scheduler = sf.getScheduler();

            //3.创建JobDetail(作业信息)
            addJob(scheduler);

            //4.启动 调度器
            scheduler.start();
            log.info("quartz start success");

        }catch (Exception e){
            log.info("quartz start fail");
            e.printStackTrace();
            //启动任务失败，强行结束
            System.exit(-1);
        }
    }

    private void addJob( Scheduler scheduler)  throws Exception{

        SchedulerEnum[] values = SchedulerEnum.values();
        for (SchedulerEnum sch :values){
            addJob(scheduler,sch.getJobCls(),sch.getInitialDelay(),sch.getCronExp());
        }
    }

    private void addJob( Scheduler scheduler ,Class<? extends Job> cls,long initialDelay,String cronExp) throws Exception{

        //任务运行的时间，SimpleScheduler类型触发器有效
        Date startTime = new Date(System.currentTimeMillis()+initialDelay);

        JobDetail jb = JobBuilder.newJob(cls)
                .withDescription("this is a job") //job的描述
                .withIdentity(cls.getSimpleName(), "monitor") //job 的name和group
                .build();

        //获取定时任务cron表达式
//        String cronExp = getStaticFieldValue(cls,"cronExpression");
//        if(null == cronExp){
//            throw  new IllegalArgumentException(cls.getSimpleName()+"cron is error");
//        }

        //向任务传递数据
//        JobDataMap jobDataMap = jb.getJobDataMap();
//        jobDataMap.put("uname", cls.getSimpleName());

        //创建Trigger
        //使用SimpleScheduleBuilder或者CronScheduleBuilder
        Trigger t = TriggerBuilder.newTrigger()
                .withDescription("")
                .withIdentity(cls.getSimpleName(), "monitor")
                .startAt(startTime)  //默认当前时间启动
                //普通计时器
                //.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(3).withRepeatCount(3))//间隔3秒，重复3次
                //表达式计时器
                .withSchedule(CronScheduleBuilder.cronSchedule(cronExp))
                .build();

        //注册任务和定时器
        scheduler.scheduleJob(jb, t);
    }

    private String getStaticFieldValue(Class<? extends Job> cls,String fieldName){

        String cronExp =null;
        try {
            Field field = cls.getField(fieldName);
            field.setAccessible(true);
            int modifiers = field.getModifiers();
            // 判断该属性是否是public final static 类型的
            // 如果想获取其它的,具体可以参考 Modifier 这个类里面的修饰符解码
            boolean flag = (Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers) && Modifier.isFinal(modifiers));
            if(flag){
                // field.get(null)  表示获取这个静态变量的值
                Object value = field.get(null);
                cronExp = (String)value;
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        return cronExp;

    }

    private List<JobDetail> getJobDetails(){
        List<JobDetail> jobDetails = new ArrayList<>();
        return jobDetails;
    }

    public static void main(String[] args) {

    }
}
